<!DOCTYPE html>
<html lang=zh>
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-transform">
  <meta http-equiv="Cache-Control" content="no-siteapp">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="format-detection" content="telephone=no,email=no,adress=no">
  <!-- Color theme for statusbar -->
  <meta name="theme-color" content="#000000">
  <!-- 强制页面在当前窗口以独立页面显示,防止别人在框架里调用页面 -->
  <meta http-equiv="window-target" content="_top">
  
  
  <title>编译构建工具-bazel | 王竹兴 | Blob</title>
  <meta name="description" content="简介 bazel是Google开源的一套类似于Make的编译构建工具。  运作原理  运行构建或测试时，Bazel执行以下操作  加载BUILD与目标相关的文件。 分析输入及其依赖关系，应用指定的构建规则。并生产action图 对输入执行构建操作，直到生成最终构建输出。   action图表示各个构建输入和他们之间的关系，以及Bazel将执行的构建操作。      优点  构建快。支持增量编译">
<meta name="keywords" content="bazel">
<meta property="og:type" content="article">
<meta property="og:title" content="编译构建工具-bazel">
<meta property="og:url" content="http://zhulao.gitee.io/blog/2019/04/05/编译构建工具-bazel/index.html">
<meta property="og:site_name" content="王竹兴 | Blog">
<meta property="og:description" content="简介 bazel是Google开源的一套类似于Make的编译构建工具。  运作原理  运行构建或测试时，Bazel执行以下操作  加载BUILD与目标相关的文件。 分析输入及其依赖关系，应用指定的构建规则。并生产action图 对输入执行构建操作，直到生成最终构建输出。   action图表示各个构建输入和他们之间的关系，以及Bazel将执行的构建操作。      优点  构建快。支持增量编译">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://ww1.sinaimg.cn/large/929ea2a1gy1g1uybdbnq2j20wu15mq7n.jpg">
<meta property="og:updated_time" content="2019-05-24T16:31:41.326Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="编译构建工具-bazel">
<meta name="twitter:description" content="简介 bazel是Google开源的一套类似于Make的编译构建工具。  运作原理  运行构建或测试时，Bazel执行以下操作  加载BUILD与目标相关的文件。 分析输入及其依赖关系，应用指定的构建规则。并生产action图 对输入执行构建操作，直到生成最终构建输出。   action图表示各个构建输入和他们之间的关系，以及Bazel将执行的构建操作。      优点  构建快。支持增量编译">
<meta name="twitter:image" content="http://ww1.sinaimg.cn/large/929ea2a1gy1g1uybdbnq2j20wu15mq7n.jpg">
  <!-- Canonical links -->
  <link rel="canonical" href="http://zhulao.gitee.io/blog/2019/04/05/编译构建工具-bazel/index.html">
  
    <link rel="alternate" href="/atom.xml" title="王竹兴 | Blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png" type="image/x-icon">
  
  <link rel="stylesheet" href="/blog/css/style.css">
  
  
  
  
</head>


<body class="main-center" itemscope itemtype="http://schema.org/WebPage">
  <header class="header" itemscope itemtype="http://schema.org/WPHeader">
  <div class="slimContent">
    <div class="navbar-header">
      
      
      <div class="profile-block text-center">
        <a id="avatar" href="https://github.com/wzx3" target="_blank">
          <img class="img-circle img-rotate" src="/blog/images/avatar.jpeg" width="200" height="200">
        </a>
        <h2 id="name" class="hidden-xs hidden-sm">王竹兴</h2>
        <h3 id="title" class="hidden-xs hidden-sm hidden-md"></h3>
        <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i> XiaMen, China</small>
      </div>
      
      <div class="search" id="search-form-wrap">

    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="搜索">
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i class="icon icon-search"></i></button>
            </span>
        </div>
    </form>
    <div class="ins-search">
  <div class="ins-search-mask"></div>
  <div class="ins-search-container">
    <div class="ins-input-wrapper">
      <input type="text" class="ins-search-input" placeholder="想要查找什么..." x-webkit-speech>
      <button type="button" class="close ins-close ins-selectable" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    </div>
    <div class="ins-section-wrapper">
      <div class="ins-section-container"></div>
    </div>
  </div>
</div>


</div>
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>
    <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
      <ul class="nav navbar-nav main-nav menu-highlight">
        
        
        <li class="menu-item menu-item-home">
          <a href="/blog/.">
            
            <i class="icon icon-home-fill"></i>
            
            <span class="menu-title">首页</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives">
            
            <i class="icon icon-archives-fill"></i>
            
            <span class="menu-title">归档</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories">
            
            <i class="icon icon-folder"></i>
            
            <span class="menu-title">分类</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-tags">
          <a href="/blog/tags">
            
            <i class="icon icon-tags"></i>
            
            <span class="menu-title">标签</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-repository">
          <a href="/blog/repository">
            
            <i class="icon icon-project"></i>
            
            <span class="menu-title">项目</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-about">
          <a href="/blog/about">
            
            <i class="icon icon-cup-fill"></i>
            
            <span class="menu-title">关于</span>
          </a>
        </li>
        
      </ul>
      
	
    <ul class="social-links">
    	
        <li><a href="https://github.com/wzx3" target="_blank" title="Github" data-toggle="tooltip" data-placement="top"><i class="icon icon-github"></i></a></li>
        
        <li><a href="/blog/atom.xml" target="_blank" title="Rss" data-toggle="tooltip" data-placement="top"><i class="icon icon-rss"></i></a></li>
        
    </ul>

    </nav>
  </div>
</header>

  
    <aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">公告</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">
                <p>人生最快意的事情之一, 就是你比别人牛逼, 然后静静的看别人在你面前装逼。</p>
            </div>
        </div>
    </div>
</div>

    
      
  <div class="widget">
    <h3 class="widget-title">分类</h3>
    <div class="widget-body">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/blog/categories/便签/">便签</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/教程/">教程</a><span class="category-list-count">22</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/游记/">游记</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/随笔/">随笔</a><span class="category-list-count">6</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">标签云</h3>
    <div class="widget-body tagcloud">
      <a href="/blog/tags/DL/" style="font-size: 13.25px;">DL</a> <a href="/blog/tags/Debug/" style="font-size: 13.5px;">Debug</a> <a href="/blog/tags/Doc/" style="font-size: 13px;">Doc</a> <a href="/blog/tags/Hexo/" style="font-size: 13.25px;">Hexo</a> <a href="/blog/tags/Links/" style="font-size: 13px;">Links</a> <a href="/blog/tags/Linux/" style="font-size: 13.25px;">Linux</a> <a href="/blog/tags/Mac/" style="font-size: 13px;">Mac</a> <a href="/blog/tags/bazel/" style="font-size: 13px;">bazel</a> <a href="/blog/tags/c-c/" style="font-size: 13.75px;">c/c++</a> <a href="/blog/tags/git/" style="font-size: 13px;">git</a> <a href="/blog/tags/rst/" style="font-size: 13px;">rst</a> <a href="/blog/tags/scripts/" style="font-size: 13.75px;">scripts</a> <a href="/blog/tags/ssh/" style="font-size: 13px;">ssh</a> <a href="/blog/tags/国学经典/" style="font-size: 13px;">国学经典</a> <a href="/blog/tags/持续集成/" style="font-size: 13.25px;">持续集成</a> <a href="/blog/tags/科幻小说/" style="font-size: 14px;">科幻小说</a>
    </div>
  </div>

    
      
  <div class="widget">
    <h3 class="widget-title">归档</h3>
    <div class="widget-body">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2019/05/">五月 2019</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2019/04/">四月 2019</a><span class="archive-list-count">10</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2019/03/">三月 2019</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2019/02/">二月 2019</a><span class="archive-list-count">10</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget-body">
      <ul class="recent-post-list list-unstyled no-thumbnail">
        
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/随笔/">随笔</a>
              </p>
              <p class="item-title">
                <a href="/blog/2019/05/26/读论语/" class="title">读论语</a>
              </p>
              <p class="item-date">
                <time datetime="2019-05-26T01:45:07.000Z" itemprop="datePublished">2019-05-26</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/随笔/">随笔</a>
              </p>
              <p class="item-title">
                <a href="/blog/2019/05/20/读变型战争/" class="title">读变型战争</a>
              </p>
              <p class="item-date">
                <time datetime="2019-05-20T15:51:57.000Z" itemprop="datePublished">2019-05-20</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/随笔/">随笔</a>
              </p>
              <p class="item-title">
                <a href="/blog/2019/05/20/读星际远征/" class="title">读黑客横行</a>
              </p>
              <p class="item-date">
                <time datetime="2019-05-20T15:40:09.000Z" itemprop="datePublished">2019-05-20</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/教程/">教程</a>
              </p>
              <p class="item-title">
                <a href="/blog/2019/05/15/代码格式化工具-clang-format/" class="title">代码格式化工具:clang-format</a>
              </p>
              <p class="item-date">
                <time datetime="2019-05-15T14:39:51.000Z" itemprop="datePublished">2019-05-15</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/教程/">教程</a>
              </p>
              <p class="item-title">
                <a href="/blog/2019/05/12/Linux-疑难杂症/" class="title">Linux 疑难杂症</a>
              </p>
              <p class="item-date">
                <time datetime="2019-05-12T02:50:29.000Z" itemprop="datePublished">2019-05-12</time>
              </p>
            </div>
          </li>
          
      </ul>
    </div>
  </div>
  

    
  </div>
</aside>

  
  
<aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    <nav id="toc" class="article-toc">
      <h3 class="toc-title">文章目录</h3>
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#入门用法"><span class="toc-number">1.</span> <span class="toc-text"> 入门用法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#项目结构"><span class="toc-number">1.1.</span> <span class="toc-text"> 项目结构</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#wrokspace"><span class="toc-number">1.1.1.</span> <span class="toc-text"> wrokspace</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#package"><span class="toc-number">1.1.2.</span> <span class="toc-text"> package</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#target"><span class="toc-number">1.1.3.</span> <span class="toc-text"> target</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#编译示例"><span class="toc-number">1.2.</span> <span class="toc-text"> 编译示例</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#如何编译"><span class="toc-number">1.2.1.</span> <span class="toc-text"> 如何编译</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#stage1-如何构建单个package中的单个target"><span class="toc-number">1.2.2.</span> <span class="toc-text"> Stage1 如何构建单个package中的单个target</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#stage2-如何构建单个package的多个target"><span class="toc-number">1.2.3.</span> <span class="toc-text"> Stage2 如何构建单个package的多个target</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#stage3-如何构建多个package的多个target"><span class="toc-number">1.2.4.</span> <span class="toc-text"> Stage3 如何构建多个package的多个target</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#如何查看依赖图"><span class="toc-number">1.2.5.</span> <span class="toc-text"> 如何查看依赖图</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#进阶用法"><span class="toc-number">2.</span> <span class="toc-text"> 进阶用法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#构建"><span class="toc-number">2.1.</span> <span class="toc-text"> 构建</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#指定包路径"><span class="toc-number">2.1.1.</span> <span class="toc-text"> 指定包路径</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#编译警告检查"><span class="toc-number">2.1.2.</span> <span class="toc-text"> 编译警告检查</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#编译器的编译选项"><span class="toc-number">2.1.3.</span> <span class="toc-text"> 编译器的编译选项</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#编译c的flag"><span class="toc-number">2.1.3.1.</span> <span class="toc-text"> 编译C的Flag</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#只适用编译c的flag"><span class="toc-number">2.1.3.2.</span> <span class="toc-text"> 只适用编译C的Flag</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#编译c的flag-2"><span class="toc-number">2.1.3.3.</span> <span class="toc-text"> 编译C++的Flag</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#编译器链接flag"><span class="toc-number">2.1.3.4.</span> <span class="toc-text"> 编译器链接Flag</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#调试与符号信息的去除"><span class="toc-number">2.1.3.5.</span> <span class="toc-text"> 调试与符号信息的去除</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#语义选项"><span class="toc-number">2.1.4.</span> <span class="toc-text"> 语义选项</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#指定编译模式"><span class="toc-number">2.1.4.1.</span> <span class="toc-text"> 指定编译模式</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#动态链接模式"><span class="toc-number">2.1.4.2.</span> <span class="toc-text"> 动态链接模式</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#输出构建过程的执行语句"><span class="toc-number">2.1.4.3.</span> <span class="toc-text"> 输出构建过程的执行语句</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#输出构建过程的性能"><span class="toc-number">2.1.4.4.</span> <span class="toc-text"> 输出构建过程的性能</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#查看构建的信息内容"><span class="toc-number">2.1.5.</span> <span class="toc-text"> 查看构建的信息内容</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#分析"><span class="toc-number">2.2.</span> <span class="toc-text"> 分析</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#是否分析host依赖相关"><span class="toc-number">2.2.1.</span> <span class="toc-text"> 是否分析host依赖相关</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#是否分析其隐式依赖关系"><span class="toc-number">2.2.2.</span> <span class="toc-text"> 是否分析其隐式依赖关系</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#指定输出格式"><span class="toc-number">2.2.3.</span> <span class="toc-text"> 指定输出格式</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#实用流程"><span class="toc-number">2.2.4.</span> <span class="toc-text"> 实用流程</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#清理"><span class="toc-number">2.3.</span> <span class="toc-text"> 清理</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#只清理编译目录"><span class="toc-number">2.3.1.</span> <span class="toc-text"> 只清理编译目录</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#完全清理"><span class="toc-number">2.3.2.</span> <span class="toc-text"> 完全清理</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#测试"><span class="toc-number">2.4.</span> <span class="toc-text"> 测试</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#运行"><span class="toc-number">2.5.</span> <span class="toc-text"> 运行</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#高阶用法"><span class="toc-number">3.</span> <span class="toc-text"> 高阶用法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#build-文件语法"><span class="toc-number">3.1.</span> <span class="toc-text"> BUILD 文件语法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#概念和术语"><span class="toc-number">3.1.1.</span> <span class="toc-text"> 概念和术语</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#通用定义"><span class="toc-number">3.1.1.1.</span> <span class="toc-text"> 通用定义</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#make变量"><span class="toc-number">3.1.1.2.</span> <span class="toc-text"> &quot;Make&quot;变量</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#函数接口"><span class="toc-number">3.1.2.</span> <span class="toc-text"> 函数接口</span></a></li></ol></li></ol></li></ol>
    </nav>
  </div>
</aside>

<main class="main" role="main">
  <div class="content">
  <article id="post-编译构建工具-bazel" class="article article-type-post" itemscope itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      
        
  
    <h1 class="article-title" itemprop="name">
      编译构建工具-bazel
    </h1>
  

      
      <div class="article-meta">
        <span class="article-date">
    <i class="icon icon-calendar-check"></i>
	<a href="/blog/2019/04/05/编译构建工具-bazel/" class="article-date">
	  <time datetime="2019-04-05T14:36:54.000Z" itemprop="datePublished">2019-04-05</time>
	</a>
</span>
        
  <span class="article-category">
    <i class="icon icon-folder"></i>
    <a class="article-category-link" href="/blog/categories/教程/">教程</a>
  </span>

        
  <span class="article-tag">
    <i class="icon icon-tags"></i>
	<a class="article-tag-link" href="/blog/tags/bazel/">bazel</a>
  </span>


        
	<span class="article-read hidden-xs">
	    <i class="icon icon-eye-fill" aria-hidden="true"></i>
	    <span id="busuanzi_container_page_pv">
			<span id="busuanzi_value_page_pv">0</span>
		</span>
	</span>


        <span class="post-comment"><i class="icon icon-comment"></i> <a href="/blog/2019/04/05/编译构建工具-bazel/#comments" class="article-comment-link">评论</a></span>
        
	
		<span class="post-wordcount hidden-xs" itemprop="wordCount">字数统计: 3,367(字)</span>
	
	
		<span class="post-readcount hidden-xs" itemprop="timeRequired">阅读时长: 14(分)</span>
	

      </div>
    </div>
    <div class="article-entry marked-body" itemprop="articleBody">
      
        <ul>
<li>
<p><strong>简介</strong></p>
<p><code>bazel</code>是<strong>Google</strong>开源的一套类似于Make的编译构建工具。</p>
<ul>
<li>运作原理
<ul>
<li>运行构建或测试时，Bazel执行以下操作
<ol>
<li>加载<code>BUILD</code>与目标相关的文件。</li>
<li>分析输入及其依赖关系，应用指定的构建规则。并生产<code>action</code>图</li>
<li>对输入执行构建操作，直到生成最终构建输出。</li>
</ol>
</li>
<li><strong>action图</strong>表示各个构建输入和他们之间的关系，以及Bazel将执行的构建操作。</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>优点</strong></p>
<ul>
<li>构建快。<strong>支持增量编译</strong>, 对依赖关系进行了优化，从而支持并发执行。</li>
<li>可构建多种语言。bazel可用来构建<strong>Java</strong> <strong>C++</strong> <strong>Android</strong> <strong>iOS</strong>等很多语言和框架，并支持<strong>mac</strong> <strong>windows</strong> <strong>linux</strong>等不同平台。</li>
<li>可伸缩。可处理任意大小的代码库，<strong>可处理多个库，也可以处理单个库</strong></li>
<li>可扩展。使用bazel扩展语言可支持新语言和新平台。</li>
</ul>
</li>
<li>
<p><strong>安装方法</strong></p>
<ul>
<li>
<p>使用<strong>Homebrew</strong>安装</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">brew uninstall bazel</span><br><span class="line"></span><br><span class="line">brew tap bazelbuild/tap</span><br><span class="line">brew tap-pin bazelbuild/tap</span><br><span class="line">brew install bazelbuild/tap/bazel</span><br><span class="line"></span><br><span class="line">bazel version</span><br><span class="line"></span><br><span class="line">brew upgrade bazelbuild/tap/bazel</span><br></pre></td></tr></table></figure>
</li>
<li>
<p>官网下载指定版本</p>
<ul>
<li><a href="https://github.com/bazelbuild/bazel/releases" target="_blank" rel="noopener">各版本下载地址</a></li>
<li><a href="http://bazel.io/docs/install.html" target="_blank" rel="noopener">详细安装教程</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="入门用法"><a class="markdownIt-Anchor" href="#入门用法"></a> 入门用法</h2>
<h3 id="项目结构"><a class="markdownIt-Anchor" href="#项目结构"></a> 项目结构</h3>
<p>​	根目录下为工作区<code>workspace</code>，<strong>workspace</strong>下包含多个<code>package</code>，每个<strong>package</strong>又包含多个编译目标<code>target</code>。</p>
<h4 id="wrokspace"><a class="markdownIt-Anchor" href="#wrokspace"></a> wrokspace</h4>
<ul>
<li>Bazel的编译是<strong>基于工作区</strong>（workspace）的概念。工作区是<strong>一个存放了所有源代码和Bazel编译输出文件的目录</strong>，也就是整个项目的根目录。同时它也包含一些Bazel认识的文件：
<ul>
<li><code>WORKSPACE</code>文件，<strong>用于指定当前文件夹就是一个Bazel的工作区</strong>。所以**<code>WORKSPACE</code>文件总是存在于项目的根目录下**。</li>
<li>一个或多个<code>BUILD</code>文件，用于告诉Bazel怎么构建项目的不同部分。（<strong>如果工作区中的一个目录包含BUILD文件，那么它就是一个package。</strong>）</li>
</ul>
</li>
<li>要指定一个目录为Bazel的工作区，就只要<strong>在该目录下创建一个空的<code>WORKSPACE</code>文件即可</strong>。</li>
<li>当Bazel编译项目时，<strong>所有的输入和依赖项都必须在同一个工作区</strong>。属于不同工作区的文件，除非linked否则彼此独立。</li>
<li><code>WORKSPACE</code>采用<strong>类似Python的语法</strong></li>
</ul>
<h4 id="package"><a class="markdownIt-Anchor" href="#package"></a> package</h4>
<ul>
<li>如果工作区中的<strong>一个目录包含BUILD文件</strong>，那么它就是一个<code>package</code>。</li>
</ul>
<h4 id="target"><a class="markdownIt-Anchor" href="#target"></a> target</h4>
<ul>
<li>一个<code>BUILD</code>文件包含了几种不同类型的<strong>指令</strong>。其中最重要的是<strong>编译指令</strong>，它告诉Bazel如何编译想要的输出，比如<strong>可执行二进制文件或库</strong>。</li>
<li><code>BUILD</code>文件中的<strong>每一条编译指令被称为一个<code>target</code></strong>，它<strong>指向一系列的源文件和依赖，一个target也可以指向别的target。</strong></li>
</ul>
<h3 id="编译示例"><a class="markdownIt-Anchor" href="#编译示例"></a> 编译示例</h3>
<blockquote>
<p>示例使用<a href="https://github.com/bazelbuild/examples/tree/master/cpp-tutorial" target="_blank" rel="noopener">官方的c++编译示例</a></p>
</blockquote>
<ul>
<li>
<p>编译示例目录结构</p>
<p>examples<br>
└── cpp-tutorial<br>
​    ├──stage1<br>
​    │  ├── main<br>
​    │  │   ├── BUILD<br>
​    │  │   └── <a href="http://hello-world.cc" target="_blank" rel="noopener">hello-world.cc</a><br>
​    │  └── WORKSPACE<br>
​    │<br>
​    ├──stage2<br>
​    │  ├── main<br>
​    │  │   ├── BUILD<br>
​    │  │   ├── <a href="http://hello-world.cc" target="_blank" rel="noopener">hello-world.cc</a><br>
​    │  │   ├── <a href="http://hello-greet.cc" target="_blank" rel="noopener">hello-greet.cc</a><br>
​    │  │   └── hello-greet.h<br>
​    │  └── WORKSPACE<br>
​    │<br>
​    └──stage3<br>
​       ├── main<br>
​       │   ├── BUILD<br>
​       │   ├── <a href="http://hello-world.cc" target="_blank" rel="noopener">hello-world.cc</a><br>
​       │   ├── <a href="http://hello-greet.cc" target="_blank" rel="noopener">hello-greet.cc</a><br>
​       │   └── hello-greet.h<br>
​       ├── lib<br>
​       │   ├── BUILD<br>
​       │   ├── <a href="http://hello-time.cc" target="_blank" rel="noopener">hello-time.cc</a><br>
​       │   └── hello-time.h<br>
​       └── WORKSPACE</p>
</li>
</ul>
<h4 id="如何编译"><a class="markdownIt-Anchor" href="#如何编译"></a> 如何编译</h4>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 在WORKSPACE文件所在根目录下执行</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> //main:是BUILD文件相对于WORKSPACE文件的位置</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> hello-world则是我们在BUILD文件中命名好的target的名字</span></span><br><span class="line">bazel build //main:hello-world</span><br></pre></td></tr></table></figure>
<h4 id="stage1-如何构建单个package中的单个target"><a class="markdownIt-Anchor" href="#stage1-如何构建单个package中的单个target"></a> Stage1 如何构建单个package中的单个target</h4>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># BUILD 文件内容</span></span><br><span class="line">cc_binary(</span><br><span class="line">    name = <span class="string">"hello-world"</span>,</span><br><span class="line">    srcs = [<span class="string">"hello-world.cc"</span>],</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h4 id="stage2-如何构建单个package的多个target"><a class="markdownIt-Anchor" href="#stage2-如何构建单个package的多个target"></a> Stage2 如何构建单个package的多个target</h4>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># BUILD 文件内容</span></span><br><span class="line">cc_library(</span><br><span class="line">    name = <span class="string">"hello-greet"</span>,</span><br><span class="line">    srcs = [<span class="string">"hello-greet.cc"</span>],</span><br><span class="line">    hdrs = [<span class="string">"hello-greet.h"</span>],</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">cc_binary(</span><br><span class="line">    name = <span class="string">"hello-world"</span>,</span><br><span class="line">    srcs = [<span class="string">"hello-world.cc"</span>],</span><br><span class="line">    deps = [</span><br><span class="line">        <span class="string">":hello-greet"</span>,</span><br><span class="line">    ],</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h4 id="stage3-如何构建多个package的多个target"><a class="markdownIt-Anchor" href="#stage3-如何构建多个package的多个target"></a> Stage3 如何构建多个package的多个target</h4>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># lib包</span></span><br><span class="line"><span class="comment">## 默认情况, targets只对同一BUILD文件里的其他targets可见</span></span><br><span class="line"><span class="comment">## 若要对其他包可见, 需声明为显示可见</span></span><br><span class="line"><span class="comment">## 防止像共有API中库的实现细节泄露等情况 </span></span><br><span class="line">cc_library(</span><br><span class="line">    name = <span class="string">"hello-time"</span>,</span><br><span class="line">    srcs = [<span class="string">"hello-time.cc"</span>],</span><br><span class="line">    hdrs = [<span class="string">"hello-time.h"</span>],</span><br><span class="line">    visibility = [<span class="string">"//main:__pkg__"</span>],</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># main包</span></span><br><span class="line">cc_library(</span><br><span class="line">    name = <span class="string">"hello-greet"</span>,</span><br><span class="line">    srcs = [<span class="string">"hello-greet.cc"</span>],</span><br><span class="line">    hdrs = [<span class="string">"hello-greet.h"</span>],</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">cc_binary(</span><br><span class="line">    name = <span class="string">"hello-world"</span>,</span><br><span class="line">    srcs = [<span class="string">"hello-world.cc"</span>],</span><br><span class="line">    deps = [</span><br><span class="line">        <span class="string">":hello-greet"</span>,</span><br><span class="line">        <span class="string">"//lib:hello-time"</span>,</span><br><span class="line">    ],</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h4 id="如何查看依赖图"><a class="markdownIt-Anchor" href="#如何查看依赖图"></a> 如何查看依赖图</h4>
<ul>
<li>
<p>生成依赖图</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 查找target为 //main:hello-world 的所有依赖</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> --nohost_deps 		表示不包括host依赖</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> --noimplicit_deps 	表示不包括隐式依赖 e.g: @bazel_tools//tools/cpp:stl</span></span><br><span class="line">bazel query --nohost_deps --noimplicit_deps 'deps(//main:hello-world)' --output graph</span><br></pre></td></tr></table></figure>
</li>
<li>
<p>将生成的输出图文字描述, 粘贴到 <a href="http://www.webgraphviz.com/" target="_blank" rel="noopener">GraphViz</a>, 生成的依赖图如下</p>
<p><img src="http://ww1.sinaimg.cn/large/929ea2a1gy1g1uybdbnq2j20wu15mq7n.jpg" alt></p>
</li>
</ul>
<h2 id="进阶用法"><a class="markdownIt-Anchor" href="#进阶用法"></a> 进阶用法</h2>
<ul>
<li>
<p><strong>bazel</strong> 可选命令</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">用法：bazel &lt;command&gt; &lt;options&gt; ...</span><br><span class="line"></span><br><span class="line">可用命令：</span><br><span class="line">	build                构建指定的目标。</span><br><span class="line">	clean                删除输出文件，并可选择停止服务器。</span><br><span class="line">	run                  运行指定的目标。</span><br><span class="line">	test                 构建并运行指定的测试目标。</span><br><span class="line">	</span><br><span class="line">	help                 打印命令或索引的帮助。</span><br><span class="line">	info                 显示有关bazel服务器的运行时信息。</span><br><span class="line">	version              打印Bazel的版本信息。</span><br><span class="line"></span><br><span class="line">  analyze-profile      分析构建配置文件数据。</span><br><span class="line">  aquery               对分析后的操作图执行查询。</span><br><span class="line">  cquery               执行分析后依赖图查询。</span><br><span class="line">  query                执行依赖关系图查询。</span><br><span class="line"></span><br><span class="line">	canonicalize-flags   Canonicalize Bazel flags。</span><br><span class="line">	dump                 转储Bazel服务器进程的内部状态。</span><br><span class="line"></span><br><span class="line">  fetch                获取目标的所有外部依赖项。</span><br><span class="line">  mobile-install       在移动设备上安装应用程序。</span><br><span class="line"></span><br><span class="line">	shutdown             停止Bazel服务器。</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="构建"><a class="markdownIt-Anchor" href="#构建"></a> 构建</h3>
<ul>
<li><strong>用法</strong></li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel build &lt;options&gt; &lt;targets&gt;</span><br></pre></td></tr></table></figure>
<h4 id="指定包路径"><a class="markdownIt-Anchor" href="#指定包路径"></a> 指定包路径</h4>
<p><code>--package_path</code> 指定搜索<strong>BUILD</strong>文件的目录集合</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p build &amp;&amp; cd build</span><br><span class="line">touch WORKSPACE</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 绝对路径</span></span></span><br><span class="line">bazel build --package_path /some/other/path //main:hello-world</span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 相对路径</span></span></span><br><span class="line">bazel build --package_path %workspace%/relative/to/other/path //main:hello-world</span><br></pre></td></tr></table></figure>
<h4 id="编译警告检查"><a class="markdownIt-Anchor" href="#编译警告检查"></a> 编译警告检查</h4>
<p><code>--output_filter regex</code> 显示那些<strong>符合正则表达式的构建和编译的警告</strong>，如果目标不匹配则标准输出和标准错误将会被丢弃。用于帮助找到某些特定的警告。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 显示所有警告</span></span></span><br><span class="line">bazel build --output_filter= --package_path /some/other/path </span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 只显示指定的某几个包(project)的警告</span></span></span><br><span class="line">--output_filter='^//(first/project|second/project):'</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 不显示指定的某几个包的警告</span></span></span><br><span class="line">--output_filter='^//((?!(first/bad_project|second/bad_project):).)*$'</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 所有警告均不显示</span></span></span><br><span class="line">--output_filter=DONT_MATCH_ANYTHING</span><br></pre></td></tr></table></figure>
<h4 id="编译器的编译选项"><a class="markdownIt-Anchor" href="#编译器的编译选项"></a> 编译器的编译选项</h4>
<h5 id="编译c的flag"><a class="markdownIt-Anchor" href="#编译c的flag"></a> 编译C的Flag</h5>
<p><code>--copt gcc-option</code> 指定给 <strong>gcc</strong> 传递什么参数, 等价于 <strong>cmake</strong> 的 <strong>CMAKE_C_FLAGS</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 参数项一次只能指定一个</span></span></span><br><span class="line">bazel build --copt="-O3" --copt="-fpic" --copt="-std=c++11" //main:hello-world</span><br></pre></td></tr></table></figure>
<h5 id="只适用编译c的flag"><a class="markdownIt-Anchor" href="#只适用编译c的flag"></a> 只适用编译C的Flag</h5>
<p><code>--conlyopt gcc-option</code> 与 <strong>—copt</strong> 相似, 不同的是<strong>只能</strong>指定 <strong>c</strong> 的编译选项</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 参数项一次只能指定一个</span></span></span><br><span class="line">bazel build --conlyopt="-Wno-pointer-sign" //main:hello-world</span><br></pre></td></tr></table></figure>
<blockquote>
<p><strong>gcc</strong>中 <strong>char</strong> 和 <strong>unsigned char</strong> 有时候传递参数类型不匹配会有报警，增加该编译选项可以关闭该报警。</p>
</blockquote>
<h5 id="编译c的flag-2"><a class="markdownIt-Anchor" href="#编译c的flag-2"></a> 编译C++的Flag</h5>
<p><code>--cxxopt gcc-option</code> 指定编 <strong>c++</strong> 的参数项, 等价于 <strong>cmake</strong> 的 <strong>CMAKE_CXX_FLAGS</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 参数项一次只能指定一个</span></span></span><br><span class="line">bazel build --cxxopt="-fno-implicit-templates" //main:hello-world</span><br></pre></td></tr></table></figure>
<blockquote>
<p>用**-fno-implicit-templates**编译代码，会令隐式的模板实例化失效，他会显示的初始化所需模板。虽然这种方法需要精确了解正在使用的是哪种模板实例，但这种方法确实令源代码更加清楚。</p>
</blockquote>
<h5 id="编译器链接flag"><a class="markdownIt-Anchor" href="#编译器链接flag"></a> 编译器链接Flag</h5>
<p><code>--linkopt linker-option</code> 指定给 <strong>gcc</strong> 的链接库选项</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel build --linkopt="-pthread" //main:hello-world</span><br></pre></td></tr></table></figure>
<h5 id="调试与符号信息的去除"><a class="markdownIt-Anchor" href="#调试与符号信息的去除"></a> 调试与符号信息的去除</h5>
<p><code>--strip (always|never|sometimes)</code> 指定是否从二进制文件和共享库文件中<strong>去除调试信息</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 默认是 sometimes, 当语义项 --compilation_mode=fastbuild 时</span></span><br><span class="line">bazel build --strip=always //main:hello-world</span><br></pre></td></tr></table></figure>
<p><strong>注:</strong></p>
<ol>
<li>
<p>即使使用了 <code>--strip=never</code> 也不会保留 <strong>debug</strong> 信息, 如果想要得到<strong>完整符号库</strong>, 需指定使用 <code>-c dbg</code> 或者 <code>--copt -g</code> 方可</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel build -c dbg --strip=never //main:hello-world</span><br></pre></td></tr></table></figure>
</li>
<li>
<p><code>--strip</code> 项默认是 <strong>–strip-debug</strong>, 如果不只是想去除 <strong>debug</strong> 信息, 而是<strong>去除所有符号信息</strong>, 则需指定链接项 <code>--strip-all</code></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel build --strip=always --linkopt=-Wl,--strip-all //main:hello-world</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p><strong>完整的编译选项文档</strong>: <a href="https://docs.bazel.build/versions/master/user-manual.html" target="_blank" rel="noopener"><strong>Commands and Options</strong></a></p>
<h4 id="语义选项"><a class="markdownIt-Anchor" href="#语义选项"></a> 语义选项</h4>
<blockquote>
<p>影响构建的命令和输出的内容。</p>
</blockquote>
<h5 id="指定编译模式"><a class="markdownIt-Anchor" href="#指定编译模式"></a> 指定编译模式</h5>
<p><code>--compilation_mode (fastbuild|opt|dbg) (-c)</code></p>
<ul>
<li><code>fastbuild</code> <strong>快速编译</strong>, 会产生最小的调试信息(<strong>-gmlt -Wl,-S</strong>), 同时将会设置 <strong>-DNDEBUG</strong>, 默认该模式</li>
<li><code>opt</code> <strong>最优化</strong>, 不会产生任何调试信息, 除非手动指定了 <strong>–copt -g</strong>, 同时设置 <strong>-O2 -DNDEBUG</strong></li>
<li><code>dbg</code> <strong>调试</strong>, 产生调试信息(<strong>-g</strong>)</li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">bazel build --compilation_mode "dbg" //main:hello-world</span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 或者使用缩写</span></span></span><br><span class="line">bazel build -c "dbg" //main:hello-world</span><br></pre></td></tr></table></figure>
<h5 id="动态链接模式"><a class="markdownIt-Anchor" href="#动态链接模式"></a> 动态链接模式</h5>
<p><code>--dynamic_mode (auto|default|fully|off)</code></p>
<ul>
<li><code>auto</code> 根据平台选择: <strong>linux</strong> 上是 <strong>default</strong>, <strong>cygwin</strong> 上是 <strong>off</strong></li>
<li><code>default</code> 由 <strong>bazel</strong> 去选择是否进行动态链接</li>
<li><code>fully</code> 动态链接所有目标, 将会加速链接时间和减小输出库大小</li>
<li><code>off</code> 静态链接所有目标, 当 <strong>linkopts</strong> 指定设置  <strong>-static</strong>, 将自动转成该模式</li>
</ul>
<h5 id="输出构建过程的执行语句"><a class="markdownIt-Anchor" href="#输出构建过程的执行语句"></a> 输出构建过程的执行语句</h5>
<p><code>--explain logfile</code> 写到一个日志文件当中, 配合 <code>—-verbose_explanations</code>, 效果等同 <strong>cmake</strong> 开启 <strong>CMAKE_VERBOSE_MAKEFILE</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel build --explain "log.txt" -—verbose_explanations //main:hello-world</span><br></pre></td></tr></table></figure>
<h5 id="输出构建过程的性能"><a class="markdownIt-Anchor" href="#输出构建过程的性能"></a> 输出构建过程的性能</h5>
<p><code>--profile file</code> 会把构建的分析数据写到一个二进制文件当中, 可使用 <code>bazel analyze-profile</code> 命令进行解析</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 生成 profile</span></span></span><br><span class="line">bazel build --profile "profile.bin" //main:hello-world</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment"># 分析构建性能</span></span></span><br><span class="line">bazel analyze-profile profile.bin</span><br></pre></td></tr></table></figure>
<p>**更多构建命令选项可参考: ** <code>bazel help build</code></p>
<h4 id="查看构建的信息内容"><a class="markdownIt-Anchor" href="#查看构建的信息内容"></a> 查看构建的信息内容</h4>
<ul>
<li>
<p><strong>命令用法</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel info &lt;options&gt; [key]</span><br></pre></td></tr></table></figure>
</li>
<li>
<p><code>--show_make_env</code>  <strong>显示构建环境</strong>, 默认 <strong>false</strong></p>
</li>
</ul>
<p>**更多信息查询命令选项可参考: ** <code>bazel help info</code></p>
<h3 id="分析"><a class="markdownIt-Anchor" href="#分析"></a> 分析</h3>
<ul>
<li><strong>命令用法</strong></li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel query &lt;options&gt; &lt;query-expression&gt;</span><br></pre></td></tr></table></figure>
<h4 id="是否分析host依赖相关"><a class="markdownIt-Anchor" href="#是否分析host依赖相关"></a> 是否分析host依赖相关</h4>
<p><code>--host_deps</code> 指定分析其依赖关系, <strong>默认开启</strong></p>
<p><code>--nohost_deps</code> 指定不分析其依赖关系</p>
<h4 id="是否分析其隐式依赖关系"><a class="markdownIt-Anchor" href="#是否分析其隐式依赖关系"></a> 是否分析其隐式依赖关系</h4>
<p><code>--implicit_deps</code> 指定分析其隐式依赖关系, 例如 <strong>@bazel_tools//tools/cpp:malloc</strong>, <strong>默认开启</strong></p>
<p><code>--noimplicit_deps</code> 指定不分析其隐式依赖关系</p>
<h4 id="指定输出格式"><a class="markdownIt-Anchor" href="#指定输出格式"></a> 指定输出格式</h4>
<p><code>--output (build|graph|label|label_kind|location|maxrank|minrank|package|proto|xml)</code></p>
<ul>
<li><code>build</code> 输出指定分析目标的 <strong>BUILD</strong> 文件内容</li>
</ul>
  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># /Users/wangzhuxing/Desktop/Project/repository/wzx3/bazel-examples/cpp-tutorial/stage1/main/BUILD:1:1</span></span><br><span class="line">cc_binary(</span><br><span class="line">  name = <span class="string">"hello-world"</span>,</span><br><span class="line">  srcs = [<span class="string">"//main:hello-world.cc"</span>],</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<ul>
<li>
<p><code>graph</code> 输出可进行<strong>图可视化</strong>的格式文本</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">digraph mygraph &#123;</span><br><span class="line">  node [shape=box];</span><br><span class="line"><span class="string">"//main:hello-world"</span></span><br><span class="line">"//main:hello-world" -&gt; "//main:hello-world.cc"</span><br><span class="line"><span class="string">"//main:hello-world.cc"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li>
<p><code>label</code> 输出指定分析目标的<strong>依赖文件</strong>, <strong>默认配置</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//main:hello-world</span><br><span class="line">//main:hello-world.cc</span><br></pre></td></tr></table></figure>
</li>
<li>
<p><code>label_kind</code> <strong>分类</strong>输出指定分析目标的依赖</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cc_binary rule //main:hello-world</span><br><span class="line">source file //main:hello-world.cc</span><br></pre></td></tr></table></figure>
</li>
<li>
<p><code>location</code> 输出指定分析目标的<strong>代码行位置</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/Users/.../main/BUILD:1:1: cc_binary rule //main:hello-world</span><br><span class="line">/Users/.../main/BUILD:3:12: source file //main:hello-world.cc</span><br></pre></td></tr></table></figure>
</li>
<li>
<p><code>maxrank|minrank</code> <strong>按等级排列</strong>指定分析目标的依赖</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">0 //main:hello-world</span><br><span class="line">1 //main:hello-world.cc</span><br></pre></td></tr></table></figure>
</li>
<li>
<p><code>package</code> 输出指定分析目标的<strong>包名</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">main</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h4 id="实用流程"><a class="markdownIt-Anchor" href="#实用流程"></a> 实用流程</h4>
<ul>
<li>生成可视化图结构的信息文本</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">bazel query --nohost_deps                                   \</span><br><span class="line">            --noimplicit_deps                               \</span><br><span class="line">            &apos;deps(//main:hello-world)&apos;              				\</span><br><span class="line">            --output graph &gt; output-graph.gv</span><br></pre></td></tr></table></figure>
<ul>
<li>通过 <strong>python</strong> 的 <code>graphviz</code>模块 进行图解析</li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python -m bazel_graphviz --input_file="output-graph.gv"</span><br></pre></td></tr></table></figure>
<p>附上本人的解析代码</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># encoding: utf-8</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> argparse, os</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> graphviz <span class="keyword">import</span> Source</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">_render</span><span class="params">(args)</span>:</span></span><br><span class="line">    <span class="keyword">if</span> args.input_file:</span><br><span class="line">        output_file_name, output_file_extension = os.path.splitext(str(args.input_file))</span><br><span class="line">        src = Source.from_file(str(args.input_file))</span><br><span class="line">        src.format = <span class="string">'png'</span></span><br><span class="line">        src.render(filename=output_file_name, view=<span class="keyword">True</span>, cleanup=<span class="keyword">True</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">True</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">False</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">_get_parser</span><span class="params">()</span>:</span></span><br><span class="line">    parser = argparse.ArgumentParser()</span><br><span class="line">    parser.add_argument(</span><br><span class="line">        <span class="string">'--input_file'</span>,</span><br><span class="line">        default=<span class="keyword">None</span>,</span><br><span class="line">        help=<span class="string">'Path to the model weights file of the external tool (e.g caffe/onnx weights proto binary)'</span>)</span><br><span class="line">    <span class="keyword">return</span> parser</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">_main</span><span class="params">()</span>:</span></span><br><span class="line">    parser = _get_parser()</span><br><span class="line">    args, unknown_args = parser.parse_known_args()</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> _render(args):</span><br><span class="line">        print(<span class="string">'Render bazel graph failed!'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    _main()</span><br></pre></td></tr></table></figure>
<p>**更多构建命令选项可参考: ** <code>bazel help query</code></p>
<h3 id="清理"><a class="markdownIt-Anchor" href="#清理"></a> 清理</h3>
<h4 id="只清理编译目录"><a class="markdownIt-Anchor" href="#只清理编译目录"></a> 只清理编译目录</h4>
<p>删除编译项目的编译过程中产生的目录树，不会删除bazel产生的临时文件</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel clean</span><br></pre></td></tr></table></figure>
<h4 id="完全清理"><a class="markdownIt-Anchor" href="#完全清理"></a> 完全清理</h4>
<p>删除输出文件的目录树，删除Bazel产生的所有临时文件，删除下载的临时文件等</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel clean --expunge</span><br></pre></td></tr></table></figure>
<h3 id="测试"><a class="markdownIt-Anchor" href="#测试"></a> 测试</h3>
<ul>
<li><strong>命令用法</strong></li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel test &lt;options&gt; &lt;test-targets&gt;</span><br></pre></td></tr></table></figure>
<p><strong>注</strong>:</p>
<ol>
<li>命令运行前会先执行一次 <strong>bazel build</strong></li>
<li>测试命令<strong>无法直接传入测试程序的形参</strong>, 也并不需要</li>
</ol>
<p>**更多测试命令选项可参考: ** <code>bazel help test</code></p>
<h3 id="运行"><a class="markdownIt-Anchor" href="#运行"></a> 运行</h3>
<ul>
<li><strong>命令用法</strong></li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bazel run &lt;options&gt; -- &lt;binary target&gt; &lt;flags to binary&gt;</span><br></pre></td></tr></table></figure>
<p>**更多运行命令选项可参考: ** <code>bazel help run</code></p>
<h2 id="高阶用法"><a class="markdownIt-Anchor" href="#高阶用法"></a> 高阶用法</h2>
<h3 id="build-文件语法"><a class="markdownIt-Anchor" href="#build-文件语法"></a> BUILD 文件语法</h3>
<h4 id="概念和术语"><a class="markdownIt-Anchor" href="#概念和术语"></a> 概念和术语</h4>
<h5 id="通用定义"><a class="markdownIt-Anchor" href="#通用定义"></a> 通用定义</h5>
<ul>
<li>
<p><strong>Bourne shell 标记化</strong></p>
<p>根据 <code>Bourne shell</code> 的标记化规则，某些规则的某些字符串属性被<strong>拆分为多个单词</strong>：</p>
<ol>
<li><strong>未加引号的空格分隔单独的单词</strong></li>
<li><strong>单引号和双引号字符和反斜杠</strong>用于防止标记化</li>
</ol>
<p>受此标记化影响的属性在本文档的定义中明确指出。</p>
<p>受**“Make”变量<strong>扩展和</strong>Bourne shell<strong>标记化的属性通常</strong>用于将任意选项传递给编译器和其他工具**。此类属性的示例是<code>cc_library.copts</code>和<code>java_library.javacopts</code>。这些替换一起允许单个字符串变量扩展为特定于配置的选项字列表。</p>
</li>
<li>
<p><strong>标签表达式</strong></p>
</li>
<li>
<p><strong>编译(build)规则的通用属性</strong></p>
</li>
<li>
<p><strong>测试(test)规则的通用属性 (*_test)</strong></p>
</li>
<li>
<p><strong>生成binary规则的通用属性 (*_binary)</strong></p>
</li>
<li>
<p><strong>可配置的属性</strong></p>
</li>
<li>
<p><strong>隐式输出目标</strong></p>
</li>
</ul>
<h5 id="make变量"><a class="markdownIt-Anchor" href="#make变量"></a> &quot;Make&quot;变量</h5>
<h4 id="函数接口"><a class="markdownIt-Anchor" href="#函数接口"></a> 函数接口</h4>
<ul>
<li><strong>参考链接</strong>
<ul>
<li><a href="https://bazel.build/" target="_blank" rel="noopener">官网</a></li>
<li><a href="https://github.com/bazelbuild/bazel" target="_blank" rel="noopener">Github地址</a></li>
<li><a href="https://github.com/bazelbuild/examples/" target="_blank" rel="noopener">Bazel 入门实例</a></li>
<li><a href="https://docs.bazel.build/versions/master/be/c-cpp.html#cc_library" target="_blank" rel="noopener">Bazel C/C++语法规则</a></li>
<li><a href="https://blog.csdn.net/elaine_bao/article/details/78668657" target="_blank" rel="noopener">部分转载出处 - Bazel入门：编译C++项目</a></li>
<li><a href="https://www.jianshu.com/p/f9ae412fde37" target="_blank" rel="noopener">部分转载处处 - Bazel构建</a></li>
</ul>
</li>
</ul>

      
    </div>
    <div class="article-footer">
      <!-- <blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    
    <li class="post-copyright-link hidden-xs">
      <strong>本文链接：</strong>
      <a href="http://zhulao.gitee.io/blog/2019/04/05/编译构建工具-bazel/" title="编译构建工具-bazel" target="_blank" rel="external">http://zhulao.gitee.io/blog/2019/04/05/编译构建工具-bazel/</a>
    </li>
    
    <li class="post-copyright-license">
      <strong>版权声明： </strong> 本博客所有文章除特别声明外，均采用 <a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN协议</a> 许可协议。转载请注明出处！
    </li>
  </ul>
</blockquote>


<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://github.com/wzx3" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="/blog/images/avatar.jpeg" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://github.com/wzx3" target="_blank"><span class="text-dark">王竹兴</span><small class="ml-1x"></small></a></h3>
        <div></div>
      </div>
    </figure>
  </div>
</div>
 -->

    </div>
  </article>
  
    
  <section id="comments">
  	
  </section>


  
</div>

  <nav class="bar bar-footer clearfix" data-stick-bottom>
  <div class="bar-inner">
  
  <ul class="pager pull-left">
    
    <li class="prev">
      <a href="/blog/2019/04/07/终端输出的字体带颜色或背景色的方法/" title="终端输出的字体带颜色或背景色的方法"><i class="icon icon-angle-left" aria-hidden="true"></i><span>&nbsp;&nbsp;上一篇</span></a>
    </li>
    
    
    <li class="next">
      <a href="/blog/2019/03/31/23种经典设计模式(附c++实现代码)/" title="23种经典设计模式(附c++实现代码)"><span>下一篇&nbsp;&nbsp;</span><i class="icon icon-angle-right" aria-hidden="true"></i></a>
    </li>
    
    
    <li class="toggle-toc">
      <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false" title="文章目录" role="button">
        <span>[&nbsp;</span><span>文章目录</span>
        <i class="text-collapsed icon icon-anchor"></i>
        <i class="text-in icon icon-close"></i>
        <span>]</span>
      </a>
    </li>
    
  </ul>
  
  
  
  <div class="bar-right">
    
    <div class="share-component" data-sites="weibo,qq,wechat,facebook,twitter" data-mobile-sites="weibo,qq,qzone"></div>
    
  </div>
  </div>
</nav>
  


</main>

  <footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
	
	
    <ul class="social-links">
    	
        <li><a href="https://github.com/wzx3" target="_blank" title="Github" data-toggle="tooltip" data-placement="top"><i class="icon icon-github"></i></a></li>
        
        <li><a href="/blog/atom.xml" target="_blank" title="Rss" data-toggle="tooltip" data-placement="top"><i class="icon icon-rss"></i></a></li>
        
    </ul>

    <div class="copyright">
    	
        <div class="publishby">
        	Theme by <a href="https://github.com/cofess" target="_blank"> cofess </a>base on <a href="https://github.com/cofess/hexo-theme-pure" target="_blank">pure</a>.
        </div>
    </div>
</footer>
  <script src="//cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>
<script src="/blog/js/plugin.min.js"></script>
<script src="/blog/js/application.js"></script>

    <script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
            UNTITLED: '(未命名)',
        },
        ROOT_URL: '/blog/',
        CONTENT_URL: '/blog/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>
<script src="/blog/js/insight.js"></script>





   
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>





   






</body>
</html>